package com.tiancheng.trade.merchant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tiancheng.trade.commom.core.data.PageInfo;
import com.tiancheng.trade.merchant.convert.OrganizationConvert;
import com.tiancheng.trade.merchant.exception.BusinessException;
import com.tiancheng.trade.merchant.mapper.OrganizationMapper;
import com.tiancheng.trade.merchant.model.Merchant;
import com.tiancheng.trade.merchant.model.Organization;
import com.tiancheng.trade.merchant.service.IMerchantService;
import com.tiancheng.trade.merchant.service.IOrgBusinessService;
import com.tiancheng.trade.merchant.service.IOrganizationService;
import com.tiancheng.trade.merchant.util.ExcelUtil;
import com.tiancheng.trade.merchant.util.UserUtils;
import com.tiancheng.trade.merchant.vo.merchant.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OrganizationService extends ServiceImpl<OrganizationMapper,Organization> implements IOrganizationService {
    @Autowired
    private OrganizationMapper organizationMapper;
    @Autowired
    private IMerchantService merchantService;
    @Autowired
    private IOrgBusinessService orgBusinessService;

    @Override
    public PageInfo<QueryOrgPageResVO> findPageList(Organization organization) throws BusinessException {
        QueryWrapper<Organization> conditions = new QueryWrapper<>();
        conditions.eq("is_delete", false);
        if (StringUtils.isNotBlank(organization.getOrganizationCode())) {
            conditions.eq("organization_code", organization.getOrganizationCode());
        }
        if (StringUtils.isNotBlank(organization.getOrganizationName())) {
            conditions.like("organization_name", organization.getOrganizationName());
        }
        conditions.orderByDesc("created_dt");
        final PageInfo<Organization> organizationPageInfo = organizationMapper.find(conditions, organization.getCurrentPage(), organization.getPageSize());
        List<QueryOrgPageResVO> convert = null;
        if(CollectionUtils.isNotEmpty(organizationPageInfo.getList())){
            convert = OrganizationConvert.INSTANCE.convert(organizationPageInfo.getList());
            QueryOrgBusinessReqVO c=new QueryOrgBusinessReqVO();
            c.setOrganizationCodes(organizationPageInfo.getList().stream().map(Organization::getOrganizationCode).collect(Collectors.toList()));
            final List<QueryOrgBusinessResVO> orgBusinessResVOS = orgBusinessService.queryList(c);
            if(CollectionUtils.isNotEmpty(orgBusinessResVOS)){
                for (QueryOrgPageResVO queryOrgPageResVO : convert) {
                    queryOrgPageResVO.setBusinessList(orgBusinessResVOS.stream().filter(o->o.getOrganizationCode().equals(queryOrgPageResVO.getOrganizationCode())).collect(Collectors.toList()));
                }
            }
        }
        return new PageInfo<>(convert,organizationPageInfo.getPagination());
    }



    @Override
    public List<Organization> findList(Organization organization) throws BusinessException {

        QueryWrapper<Organization> conditions = new QueryWrapper<>();
        conditions.eq("is_delete", false);

        if (StringUtils.isNotBlank(organization.getOrganizationCode())) {

            conditions.eq("organization_code", organization.getOrganizationCode());
        }
        if (StringUtils.isNotBlank(organization.getOrganizationName())) {

            conditions.like("organization_name", organization.getOrganizationName());
        }
        conditions.orderByDesc("created_dt");
        return organizationMapper.selectList(conditions);
    }


    @Override
    public int remove(Long id) throws BusinessException {

        Organization org = organizationMapper.selectById(id);

        Assert.notNull(org, "删除失败，该组织不存在或已删除");

        GetMerchantVO merchant = new GetMerchantVO();
        merchant.setIsDelete(0);
        merchant.setOrganizationCode(org.getOrganizationCode());
        List<Merchant> list = merchantService.findList(merchant);

        // 如果组织下面有商户，不给删除
        Assert.isTrue(CollectionUtils.isEmpty(list), "已有关联商户,不允许删除");

        org.setIsDelete(1);
        org.setLastUpdBy(UserUtils.currentUserId());//删除人
        org.setLastUpdDt(LocalDateTime.now());

        return organizationMapper.updateById(org);
    }

    @Override
    public int update(Organization org) throws BusinessException {
        List<Organization> list = findOrganByCodeName(org);
        Assert.isTrue(CollectionUtils.isEmpty(list), "此组织编号或名称已存在");
        Organization organization = new Organization();
        organization.setOrganizationName(org.getOrganizationName());
        organization.setRemark(org.getRemark());
        organization.setId(org.getId());
        organization.setLastUpdDt(LocalDateTime.now());
        organization.setLastUpdBy(UserUtils.currentUserId());
        return organizationMapper.updateById(organization);
    }

    public void test() {
        QueryWrapper<Organization> conditions = new QueryWrapper<Organization>();
        conditions.isNull("organization_code");
        List<Organization> organization = organizationMapper.selectList(conditions);
        for (Organization o : organization) {
            String content = o.getOrganizationName() + String.valueOf(o.getCreatedDt()).substring(0, 19);
            o.setOrganizationCode(DigestUtils.md5DigestAsHex(content.getBytes()).toUpperCase());
            organizationMapper.updateById(o);
        }
    }

    @Override
    public int create(Organization org) throws BusinessException {
        Organization organization = new Organization();
        organization.setOrganizationCode(org.getOrganizationCode());
        organization.setOrganizationName(org.getOrganizationName());
        organization.setRemark(org.getRemark());
        organization.setCreatedDt(LocalDateTime.now());
        //organization.setCreatedBy(UserUtils.currentUserId());
        List<Organization> list = findOrganByCodeName(org);
        Assert.isTrue(CollectionUtils.isEmpty(list), "此组织编号或名称已存在");

        // organizationCode 自动生成
        if (StringUtils.isEmpty(org.getOrganizationCode())) {
            String content = organization.getOrganizationName() + String.valueOf(organization.getCreatedDt()).substring(0, 19);
            organization.setOrganizationCode(DigestUtils.md5DigestAsHex(content.getBytes()).toUpperCase());
        }
        return organizationMapper.insert(organization);
    }

    @Override
    public Organization findDetail(Long id) throws BusinessException {

        Organization org = organizationMapper.selectById(id);
        Assert.notNull(org, "删除失败，该组织不存");
        Assert.isTrue(org.getIsDelete()==0, "删除失败，该组织已删除");
        return org;
    }

    /**
     * 按组织编号或名称查询是否已经存在同名组织
     *
     * @param org
     * @return
     */
    private List<Organization> findOrganByCodeName(Organization org) {
        QueryWrapper<Organization> conditions = new QueryWrapper<Organization>();
        conditions.eq("is_delete", "0");
        if (null != org.getId()) {
            conditions.ne("id", org.getId());
        }
        if (StringUtils.isNotEmpty(org.getOrganizationName()) && StringUtils.isEmpty(org.getOrganizationCode())) {
            conditions.eq("organization_name", org.getOrganizationName());
        }
        if (StringUtils.isNotEmpty(org.getOrganizationName()) && StringUtils.isNotEmpty(org.getOrganizationCode())) {
            conditions.and(wrapper -> wrapper.eq("organization_name", org.getOrganizationName()).or().eq("organization_code", org.getOrganizationCode()));
        }
        return organizationMapper.selectList(conditions);
    }

    /**
     * 组织信息导出
     *
     * @param organization
     * @param request
     * @param response
     * @throws IOException
     */
    public void export(Organization organization, HttpServletRequest request, HttpServletResponse response) throws IOException {

        QueryWrapper<Organization> conditions = new QueryWrapper<>();
        conditions.select("organization_code", "organization_name", "remark");

        conditions.eq("is_delete", false);
        if (StringUtils.isNotBlank(organization.getOrganizationCode())) {
            conditions.eq("organization_code", organization.getOrganizationCode());
        }
        if (StringUtils.isNotBlank(organization.getOrganizationName())) {
            conditions.like("organization_name", organization.getOrganizationName());
        }
        conditions.orderByDesc("created_dt");
        List<Organization> list = organizationMapper.selectList(conditions);
        List<OrganizationExpVO> listExp = new ArrayList<OrganizationExpVO>();
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(a -> {
                OrganizationExpVO expVO = new OrganizationExpVO();
                expVO.setOrganizationCode(a.getOrganizationCode());
                expVO.setOrganizationName(a.getOrganizationName());
                expVO.setRemark(a.getRemark());
                listExp.add(expVO);
            });
        }
        List<Map<String, Object>> mapList = listConvert(listExp);

        String fileName = "组织信息.xlsx";

        String[] title = {"机构编码", "机构名称", "备注"};
        Workbook workbook = ExcelUtil.buildWorkbook("组织信息", title, mapList);

        ExcelUtil.exportExcle(request, response, workbook, fileName);
    }

    @Override
    public List<Organization> findAll() {
        return this.findOrganByCodeName(new Organization());
    }

    /**
     * 数据转换
     *
     * @param list
     * @return
     */
    private List<Map<String, Object>> listConvert(List<OrganizationExpVO> list) {
        List<Map<String, Object>> list_map = new ArrayList<Map<String, Object>>();
        try {
            for (OrganizationExpVO t : list) {
                Field[] fields = t.getClass().getDeclaredFields();
                Map<String, Object> m = new LinkedHashMap<String, Object>();
                for (Field field : fields) {
                    String keyName = field.getName();
                    PropertyDescriptor pd = new PropertyDescriptor(keyName, t.getClass());
                    Method getMethod = pd.getReadMethod();// 获得getter方法
                    Object o = getMethod.invoke(t);// 执行get方法返回一个Object
                    m.put(keyName, o);
                }
                list_map.add(m);
            }
            return list_map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
